#include <vector>
#include <windows.h>
#include "StageParam.h"
#include "KeyboardDispatch.h"
#include "MouseDispatch.h"

#include <gl\gl.h>
#include <glut.h>
#include <cstdlib>

#include "Timer.h"
#include "renderBlock.h"
#include "renderFloor.h"

int width = 800;
int height = 600;

Dispatch *dispatch;
KeyboardDispatch *keyboarder;
MouseDispatch *mouser;
Timer *timer;

static int screen_win_width = 800, screen_win_height = 600;

//Pulses every interval defined as the timer
void timerPulse(int value){
	if (timer->IsStopped() != true)
	{
		// Do an action
		timer->pulse();
		// Get ready for the next interval
		glutTimerFunc(timer->getInterval(), timerPulse, value);
	}

}

void init (void) {
	glEnable(GL_DEPTH_TEST); //enable the depth testing
	glShadeModel(GL_SMOOTH); //set the shader to smooth shader
}

void display (void) {

	// clear colour is black
	glClearColor(0.0,0.0,0.0,1.0);
	// clear the buffer for redraw
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
	glLoadIdentity();  

	// dispatch will call the appropriate functions
	// to get a render done
	dispatch->doRender();

	glutSwapBuffers(); 
	//swap the buffers

}

void reshape (int w, int h) {
	width = w;
	height = h;
	//set the viewport to the current window specifications
	glViewport (0, 0, (GLsizei)w, (GLsizei)h);
	//set the matrix to projection
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	//set the perspective (angle of sight, width, height, , depth)
	gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 500.0f);
	//set the matrix back to model
	glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
	// keyboarder is responsible for some dispatch events
	keyboarder->keyboard(key, x, y);
}

void keyboard2(int key, int x, int y)
{
	// keyboarder is responsible for some dispatch events
	keyboarder->keyboard(key,x,y);
}

void mouse(int button, int state, int x, int y)
{
	// mouser is responsible for some dispatch events
	mouser->MousePress(button, state, x, y);
}

void mousemove(int x, int y)
{
	// mouser is responsible for some dispatch events
	mouser->MouseMove(x, y);
}


void tmr(int value)
{
	// redraw timer
	glutPostRedisplay();
	glutTimerFunc(10, tmr, value);
}

void main(int argc, char** argv )
{
	// make a new keyboard, mouse, timer
	// and dispatcher
	dispatch = new Dispatch();
	keyboarder= new KeyboardDispatch(dispatch);
	mouser = new MouseDispatch(dispatch);
	timer = new Timer(0,100,dispatch);

	// initialize glut with the arguments
	glutInit(&argc, argv);
	// initialize as a double buffered project with RGB
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); //set the display to Double buffer, with depth
	// initialize the window size
	glutInitWindowSize (width, height); 
	// initialize the position
	glutInitWindowPosition (200, 100);
	// create our window with the above initializations
	glutCreateWindow ("Tait's Turmoil");

	// set up our drawing tools
	init();
	// the following are our glut Special Events
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(keyboard2);
	glutMouseFunc(mouse);
	glutMotionFunc(mousemove);
	glutTimerFunc(1000, timerPulse,1);
	glutTimerFunc(33, tmr, 0);
	// loop
	glutMainLoop();

}
